import com.alibaba.fastjson.JSON;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

// 游戏主界面
public class GameGUI extends JFrame implements MouseListener {
    public final static int SIZE = 20; //棋盘格子数
    public final static int WIDTH = 910; // 界面宽
    public final static int HEIGHT = 730;// 界面高
    private static SocketClinet socketClinet;
    private static SocketServe socketServe;
    public Chess chess;
    private boolean chessFlag = false; // 是否自己下棋
    private boolean ready = false;
    private boolean start = false;
    private int type = 0; //自己是黑棋还是白棋 1黑 2白
    List<JButton> jButtons = new ArrayList<>();
    String[] btnTitle = {"新建连接", "加入连接", "认输", "开始", "准备"};
    List<JTextField> inputs = new ArrayList<>();
    private JLabel jLabel[] = new JLabel[2];

    public void setType(int type) {
        this.type = type;
    }

    public int getChessType() {
        return type;
    }

    public void setChessFlag(boolean chessFlag) {
        this.chessFlag = chessFlag;
    }

    public boolean isReady() {
        return ready;
    }

    public void setReady(boolean ready) {
        this.ready = ready;
    }

    public boolean isStart() {
        return start;
    }

    public void setStart(boolean start) {
        this.start = start;
    }


    public JLabel[] getjLabel() {
        return jLabel;
    }

    public GameGUI(String title, Chess chess) {
        super(title);
        this.chess = chess;

        this.setSize(WIDTH, HEIGHT);
        this.setLocation(300, 200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 点击x退出
        this.setResizable(false); // 窗口大小不可修改
        addEvent();
        addLinstener();
        this.addMouseListener(this);
    }

    private void addEvent() {
        JPanel panel = new JPanel();
        panel.setLayout(null);
        for (int i = 0; i < 2; i++) {
            JTextField txt = new JTextField();
            JLabel nameLabel = new JLabel(i == 0 ? "主机 :" : "端口 :");
            txt.setBounds(680, 100 + i * 60, 170, 25);
            nameLabel.setBounds(630, 100 + i * 60, 50, 25);
            inputs.add(txt);
            panel.add(txt);
            panel.add(nameLabel);

        }

        for (int i = 0; i < btnTitle.length; i++) {
            JButton jButton = new JButton(btnTitle[i]);
            jButton.setBounds(650, 200 + i * 40, 180, 30);// 设置位置及大小
            panel.add(jButton);
            if (i > 1) {
                jButton.setEnabled(false);
            }
            jButtons.add(jButton);
        }
        jLabel[0] = new JLabel("", JLabel.CENTER);
        jLabel[0].setText("");
        jLabel[0].setFont(new java.awt.Font("Dialog", 1, 17));
        jLabel[0].setBounds(650, 400, 180, 35);
        jLabel[1] = new JLabel("", JLabel.CENTER);
        jLabel[1].setText("");
        jLabel[1].setFont(new java.awt.Font("Dialog", 1, 17));
        jLabel[1].setBounds(650, 460, 180, 35);
        panel.add(jLabel[0]);
        panel.add(jLabel[1]);
        getContentPane().add(panel);
    }

    public Chess getChess() {
        return chess;
    }

    //建立连接
    private void creatConnection() {
        if (null == inputs.get(1).getText() || "".equals(inputs.get(1).getText())) {
            JOptionPane.showMessageDialog(null,
                    "请输入端口",
                    "提示",
                    JOptionPane.DEFAULT_OPTION);
            return;
        }
        Integer port = Integer.valueOf(inputs.get(1).getText());
        socketServe = new SocketServe(this, port);
        jButtons.get(1).setEnabled(false);

        // 开启线程接收连接
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socketServe.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    //加入连接
    private void connection() {
        try {
            JTextField jTextField = inputs.get(0);
            String host = jTextField.getText();
            Integer port = Integer.valueOf(inputs.get(1).getText());
            socketClinet = new SocketClinet(host, port, this);
            jButtons.get(4).setEnabled(true); //准备可用
            jButtons.get(0).setEnabled(false); // 创建连接不可用
            socketClinet.start();
        } catch (IOException e) {
            jButtons.get(0).setEnabled(true);
            jButtons.get(4).setEnabled(false); //准备不可用
            socketClinet = null; // 失败之后把客户端置空，不然客户端对象和服务端对象都不为null
            JOptionPane.showMessageDialog(null,
                    "没有可用连接，请先创建连接",
                    "提示",
                    JOptionPane.DEFAULT_OPTION);
//            e.printStackTrace();
        }

    }

    private void sendMsg(String msg) {
        try {
            if (null != socketClinet) {
                socketClinet.setSendMsg(msg);
            } else if (null != socketServe) {
                socketServe.setMsg(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void resetBtn() {
        if (null != socketClinet) {
            jButtons.get(4).setEnabled(true);
        } else if (null != socketServe) {
            jButtons.get(3).setEnabled(true);
        }
    }

    //认输
    private void giveup() {
        Message message = new Message();
        message.setType(type);
        message.setEventName("giveup");
        String s = JSON.toJSONString(message);
        sendMsg(s);
        jLabel[0].setText("你输了");
        //认输后客户端可以点准备
        resetRead();

        jButtons.get(2).setEnabled(false);
    }

    //准备
    private void reading() {
        Message message = new Message();
        message.setType(type);
        message.setEventName("reading");
        String s = JSON.toJSONString(message);
        jButtons.get(4).setEnabled(false);
        jButtons.get(4).setText("准备中...");
        sendMsg(s);
    }

    //开始
    private void startGame() {
        getChess().reset();
        repaint();
        int i = Integer.parseInt(new DecimalFormat("0").format(Math.random())) + 1;
        setType(i);
        System.out.println("开始游戏 type: " + i);
        if (i == 1) {
            setChessFlag(true);
            jLabel[0].setText("现在是黑棋下");
            jLabel[1].setText("你是黑棋");
        } else {
            setChessFlag(false);
            jLabel[0].setText("现在是黑棋下");
            jLabel[1].setText("你是白棋");

        }
        Message message = new Message();
        message.setContent((i == 1 ? 2 : 1) + ""); //对手的棋子类型 1黑2白棋
        message.setEventName("reGame");
        message.setType(type);
        jButtons.get(2).setEnabled(true);
        jButtons.get(3).setEnabled(false);
        setStart(true);
        String s = JSON.toJSONString(message);
        sendMsg(s);
    }

    //按钮加监听
    private void addLinstener() {
        for (int i = 0; i < jButtons.size(); i++) {
            JButton jButton = jButtons.get(i);
            int finalI = i;
            jButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    switch (finalI) {
                        case 0:
                            creatConnection();
                            break;
                        case 1:
                            connection();
                            break;
                        case 2:
                            giveup();
                            break;
                        case 3:
                            startGame();
                            break;
                        case 4:
                            reading();
                            break;
                    }
                }
            });
        }
    }

    @Override
    // 画棋盘
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        // 横
        for (int i = 1; i < SIZE + 1; i++) {
//            g.drawString(String.format("%2d", ""), 30 * i - 5, 45);
            g.drawString("", 30 * i - 5, 45);

//            g.drawString(String.format("%2d", ""), 10, 30 * i + 35);
            g.drawString("", 10, 30 * i + 35);

            g.drawLine(30, 30 + i * 30, WIDTH - 310, 30 + i * 30);
        }
        // 竖线
        for (int i = 0; i < SIZE; i++) {
            // 线起点和终点坐标
            g.drawLine(30 + i * 30, 60, 30 + i * 30, HEIGHT - 100);
        }
        int[][] board = chess.Edge;
        // 画棋子
        for (int i = 1; i <= SIZE; i++) {
            for (int j = 1; j <= SIZE; j++) {
                // 白棋棋子
                if (board[j][i] == 2) {
                    URL resource = getClass().getClassLoader().getResource("bqizi.png");
                    try {
                        g.drawImage(ImageIO.read(resource), i * 30 - 10, 20 + j * 30, 20, 20, null, null);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
//                    g.drawOval(i * 30 - 10, 20 + j * 30, 20, 20);

                }
                // 黑棋
                if (board[j][i] == 1) {
                    URL resource = getClass().getClassLoader().getResource("hqizi.png");
                    try {
                        g.drawImage(ImageIO.read(resource), i * 30 - 10, 20 + j * 30, 20, 20, null, null);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
//                    g.fillOval(i * 30 - 10, 20 + j * 30, 20, 20);

                }
            }
        }
    }

    public void resetRead() {
        if (null != socketClinet) {
            jButtons.get(4).setText("准备");
            jButtons.get(4).setEnabled(true);
        }
    }

    //鼠标监听事件
    @Override
    public void mousePressed(MouseEvent e) {
        if (!(chessFlag && start)) {
            return;
        }

        //获取棋盘上的位置e.getX() 点击位置离交叉点太远的舍弃
        if (!((e.getX() - 15) % 30 > 10 && (e.getY() - 45) % 30 > 10)) {
            return;
        }
        int col = (e.getX() - 15) / 30 + 1;
        int row = (e.getY() - 45) / 30 + 1;
        if (col > SIZE || row > SIZE) return;
        if (!(chess.getE(row, col) == 0 && col >= 1 && col <= SIZE && row >= 1 && row <= SIZE)) {
            return;
        }
        // 下棋
        chess.putChess(row, col, type);
        chessFlag = false;
        //界面重画
        this.repaint();
        //判断输赢
        int WinOrLose = chess.WinOrLose(row, col);
        // 游戏结束 客户端准备按钮可点击
        if (WinOrLose == 1) {
            if (type == WinOrLose) {
                JOptionPane.showMessageDialog(null,
                        "你赢了",
                        "恭喜",
                        JOptionPane.DEFAULT_OPTION);
            }
            // 游戏结束
            resetRead();
            Message message = new Message();
            message.setEventName("gameOver");
            message.setType(1);
            String s = JSON.toJSONString(message);
            sendMsg(s);
            jButtons.get(2).setEnabled(false);
            return;
        } else if (WinOrLose == 2) {
            if (type == WinOrLose) {
                JOptionPane.showMessageDialog(null,
                        "你赢了",
                        "恭喜",
                        JOptionPane.DEFAULT_OPTION);
            }
            resetRead();
            Message message = new Message();
            message.setEventName("gameOver");
            message.setType(2);
            String s = JSON.toJSONString(message);
            sendMsg(s);
            jButtons.get(2).setEnabled(false);
            return;
        }

        int[][] edge = chess.getEdge();
        Message message = new Message();
        message.setType(type);
        message.setEventName("msg");
        String s = JSON.toJSONString(edge);
        message.setContent(s);
        String s1 = JSON.toJSONString(message);
        if (type == 1) {
            jLabel[0].setText("现在是白棋下");
        } else {
            jLabel[0].setText("现在是黑棋下");
        }
        if (null != socketClinet)
            socketClinet.setSendMsg(s1);
        else if (null != socketServe) {
            socketServe.setMsg(s1);
        }
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }
}